home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir24 / jnos110g.zip / SESSION.C < prev    next >
C/C++ Source or Header  |  1994-04-17  |  14KB  |  556 lines

  1. /* NOS User Session control
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by PA0GRI
  5.  */
  6. #include "global.h"
  7. #include "config.h"
  8. #include "mbuf.h"
  9. #include "proc.h"
  10. #include "ftpcli.h"
  11. #include "icmp.h"
  12. #include "telnet.h"
  13. #include "tty.h"
  14. #include "session.h"
  15. #include "hardware.h"
  16. #include "socket.h"
  17. #include "cmdparse.h"
  18. #include "rlogin.h"
  19. #include "commands.h"
  20. #include "main.h"
  21. #include "pc.h"
  22.   
  23. struct session *Sessions;
  24. struct session *Command;
  25. struct session *Current;
  26. struct session *Lastcurr;
  27. extern struct session *Trace;
  28. int Row;
  29. int Morewait;
  30. extern int Numrows;
  31. extern int StatusLines;
  32.   
  33. char Notval[] = "Not a valid control block\n";
  34. static char Badsess[] = "Invalid session\n";
  35. char TooManySessions[] = "Too many sessions\n";
  36.   
  37. char *Sestypes[] = {
  38.     "Command",
  39.     "Telnet",
  40.     "FTP",
  41.     "AX25",
  42.     "Finger",
  43.     "Ping",
  44.     "NET/ROM",
  45.     "Command",
  46.     "More",
  47.     "Hopcheck",
  48.     "Tip",
  49.     "PPP PAP",
  50.     "Dial",
  51.     "Query",
  52.     "Cache",
  53.     "Rlogin",
  54.     "Repeat",
  55.     "Look",
  56.     "Trace"
  57. };
  58.   
  59. /* Convert a character string containing a decimal session index number
  60.  * into a pointer. If the arg is NULLCHAR, use the current default session.
  61.  * If the index is out of range or unused, return NULLSESSION.
  62.  */
  63. struct session *
  64. sessptr(cp)
  65. char *cp;
  66. {
  67.     struct session *sp;
  68.     unsigned int i;
  69.   
  70.     if(cp == NULLCHAR){
  71.         sp = Lastcurr;
  72.     } else {
  73.         i = (unsigned)atoi(cp);
  74.         if(i >= Nsessions)
  75.             sp = NULLSESSION;
  76.         else
  77.             sp = &Sessions[i];
  78.     }
  79.     if(sp == NULLSESSION || sp->type == FREE)
  80.         sp = NULLSESSION;
  81.   
  82.     return sp;
  83. }
  84.   
  85. /* Select and display sessions */
  86. int
  87. dosession(argc,argv,p)
  88. int argc;
  89. char *argv[];
  90. void *p;
  91. {
  92.     struct session *sp;
  93.     struct sockaddr fsocket;
  94.     int i,k,s;
  95.     int r,t;
  96.     char *cp,swap;
  97.     char *param[3];
  98.   
  99.     sp = (struct session *)p;
  100.   
  101.     if(argc > 1){
  102.         if(strncmpi(argv[1],"swap",strlen(argv[1])) == 0) {
  103.             if(argc == 2) {
  104. #ifdef EMS
  105.                 if(SwapMode == EMS_SWAP)
  106.                     tputs("EMS\n");
  107.                 else
  108. #endif
  109. #ifdef XMS
  110.                     if(SwapMode == XMS_SWAP)
  111.                         tputs("XMS\n");
  112.                     else
  113. #endif
  114.                         if(SwapMode == MEM_SWAP)
  115.                             tputs("Memory\n");
  116.                         else
  117.                             tputs("Tmp files\n");
  118.             } else {
  119. #ifdef EMS
  120.                 if(*argv[2] == 'e' || *argv[2] == 'E') {
  121.                     SwapMode = EMS_SWAP;
  122.                 } else
  123. #endif
  124. #ifdef XMS
  125.                     if(*argv[2] == 'x' || *argv[2] == 'X') {
  126.                         if(!ScreenSizeK)
  127.                             ScreenSizeK = (ScreenSize / 1024) + 1;
  128.                         SwapMode = XMS_SWAP;
  129.                     } else
  130. #endif
  131.                         if(*argv[2] == 'f' || *argv[2] == 'F') {
  132.                             SwapMode = FILE_SWAP;
  133.                         } else {
  134.                             SwapMode = MEM_SWAP;
  135.                         }
  136.             }
  137.             return 0;
  138.         }
  139.         if((sp = sessptr(argv[1])) == NULLSESSION){
  140.             tprintf("Session %s not active\n",argv[1]);
  141.             return 1;
  142.         }
  143.         if(argc == 2){
  144.             go(0,NULL,sp);
  145.         } else {
  146.             switch (*argv[2]) {
  147.                 case 'f':   /* flowmode */
  148.                     param[0] = argv[2];
  149.                     param[1] = argv[3];
  150.                     param[2] = NULL;
  151.                     setbool(&sp->flowmode,"Set flowmode on/off",argc-2,param);
  152.                     break;
  153.                 default:
  154.                     tprintf("usage:session # [flow [on/off]]\n");
  155.             }
  156.         }
  157.         return 0;
  158.     }
  159.     tputs(" #  S#  Sw Type     Rcv-Q Snd-Q State        Remote socket\n");
  160.     for(sp=Sessions; sp < &Sessions[Nsessions];sp++){
  161.         if(sp->type == FREE || sp->type == COMMAND || sp->type == TRACESESSION)
  162.             continue;
  163.   
  164.         /* Rcv-Q includes output pending at the screen driver */
  165.         r = socklen(sp->output,1);
  166.         t = 0;
  167.         cp = NULLCHAR;
  168.         if((s = sp->s) != -1){
  169.             i = SOCKSIZE;
  170. /*            s = sp->s; */
  171.             k = getpeername(s,(char *)&fsocket,&i);
  172.             r += socklen(s,0);
  173.             t = socklen(s,1);
  174.             cp = sockstate(s);
  175.         }
  176. #ifdef EMS
  177.         if(sp->screen->stype == EMS_SWAP)
  178.             swap = 'E';
  179.         else
  180. #endif
  181. #ifdef XMS
  182.             if(sp->screen->stype == XMS_SWAP)
  183.                 swap = 'X';
  184.             else
  185. #endif
  186.                 if(sp->screen->stype == FILE_SWAP)
  187.                     swap = 'F';
  188.                 else swap = 'M';
  189.   
  190.         tputc((Lastcurr == sp)?'*':' ');
  191.         tprintf("%-3u", (unsigned)(sp - Sessions));
  192.         tprintf("%-4d%c  %-8s%6d%6d %-13s",
  193.         s,swap,Sestypes[sp->type],r,t,(cp != NULLCHAR) ? cp : "Limbo!");
  194.         if(sp->name != NULLCHAR)
  195.             tprintf("%s ",sp->name);
  196.         if(sp->s != -1 && k == 0)
  197.             tprintf("(%s)",psocket(&fsocket));
  198.         tputc('\n');
  199.   
  200.         if(sp->type == FTP && (s = sp->cb.ftp->data) != -1){
  201.             /* Display data channel, if any */
  202.             i = SOCKSIZE;
  203.             k = getpeername(s,(char *)&fsocket,&i);
  204.             r = socklen(s,0);
  205.             t = socklen(s,1);
  206.             cp = sockstate(s);
  207.             tprintf("    %-4d   %-8s%6d%6d %-13s%s",
  208.             s,Sestypes[sp->type],r,t,
  209.             (cp != NULLCHAR) ? cp : "Limbo!",
  210.             (sp->name != NULLCHAR) ? sp->name : "");
  211.             if(k == 0)
  212.                 tprintf(" (%s)",psocket(&fsocket));
  213.             if(tputc('\n') == EOF)
  214.                 break;
  215.         }
  216.         if(sp->rfile != NULLCHAR)
  217.             tprintf("    Record: %s\n",sp->rfile);
  218.         if(sp->ufile != NULLCHAR)
  219.             tprintf("    Upload: %s\n",sp->ufile);
  220.     }
  221.     return 0;
  222. }
  223. /* Resume current session, and wait for it */
  224. int
  225. go(argc,argv,p)
  226. int argc;
  227. char *argv[];
  228. void *p;
  229. {
  230.     struct session *sp;
  231.   
  232.     sp = (struct session *)p;
  233.     if(sp == NULLSESSION || sp->type == FREE || \
  234.         sp->type == COMMAND || sp->type == TRACESESSION)
  235.         return 0;
  236.     Current = sp;
  237.     swapscreen(Command,sp);
  238. #ifdef STATUSWIN
  239.     UpdateStatus();
  240. #endif
  241.     psignal(sp,0);
  242.     return 0;
  243. }
  244. int
  245. doclose(argc,argv,p)
  246. int argc;
  247. char *argv[];
  248. void *p;
  249. {
  250.     struct session *sp;
  251.   
  252.     sp = (struct session *)p;
  253.     if(argc > 1)
  254.         sp = sessptr(argv[1]);
  255.   
  256.     if(sp == NULLSESSION){
  257.         tputs(Badsess);
  258.         return -1;
  259.     }
  260.     shutdown(sp->s,1);
  261.     if(sp->type == MORE || sp->type == LOOK)
  262.         alert(sp->proc,EABORT);
  263.     return 0;
  264. }
  265. int
  266. doreset(argc,argv,p)
  267. int argc;
  268. char *argv[];
  269. void *p;
  270. {
  271.     struct session *sp;
  272.   
  273.     sp = (struct session *)p;
  274.     if(argc > 1)
  275.         sp = sessptr(argv[1]);
  276.   
  277.     if(sp == NULLSESSION){
  278.         tputs(Badsess);
  279.         return -1;
  280.     }
  281.     /* Unwedge anyone waiting for a domain resolution, etc */
  282.     alert(sp->proc,EABORT);
  283.     shutdown(sp->s,2);
  284.     if(sp->type == FTP)
  285.         shutdown(sp->cb.ftp->data,2);
  286.     return 0;
  287. }
  288. int
  289. dokick(argc,argv,p)
  290. int argc;
  291. char *argv[];
  292. void *p;
  293. {
  294.     struct session *sp;
  295.   
  296.     sp = (struct session *)p;
  297.     if(argc > 1)
  298.         sp = sessptr(argv[1]);
  299.   
  300.     if(sp == NULLSESSION){
  301.         tputs(Badsess);
  302.         return -1;
  303.     }
  304.     sockkick(sp->s);
  305.     if(sp->type == FTP)
  306.         sockkick(sp->cb.ftp->data);
  307.     return 0;
  308. }
  309.   
  310. struct session *
  311. newsession(name,type,split)
  312. char *name;
  313. int type;
  314. int split;
  315. {
  316.     struct session *sp;
  317.     int i;
  318.   
  319.     /* Make sure we have enough memory to swap the old session out - WG7J */
  320.     if(availmem() < Memthresh/2 + ScreenSize)
  321.         return NULLSESSION;
  322.   
  323.     /* Reserve the highest session for Trace, so that
  324.      * the F-key session switching works correctly - WG7J
  325.      */
  326.     if(type == TRACESESSION) { /* This can only get called once !! */
  327.         i=0;
  328.         sp=Sessions;
  329.         while(i!=Nsessions-1) {
  330.             i++;
  331.             sp++;
  332.         }
  333.     } else {
  334.         for(i=0,sp=Sessions;i < Nsessions;sp++,i++)
  335.             if(sp->type == FREE)
  336.                 break;
  337.     }
  338.     if(i == Nsessions)
  339.         return NULLSESSION;
  340.   
  341.     sp->curdirs = NULL;
  342.     sp->num = i;
  343.     sp->type = type;
  344.     sp->s = -1;
  345.     if(name != NULLCHAR)
  346.         sp->name = strdup(name);
  347.     sp->proc = Curproc;
  348.     /* Create standard input and output sockets. Output is
  349.      * translated to local end-of-line by default
  350.      */
  351.     if(type != TRACESESSION) {
  352.         close_s(Curproc->input);
  353.         Curproc->input =  sp->input = socket(AF_LOCAL,SOCK_STREAM,0);
  354.         seteol(Curproc->input,Eol);
  355.         sockmode(Curproc->input,SOCK_BINARY);
  356.         close_s(Curproc->output);
  357.         Curproc->output = sp->output = socket(AF_LOCAL,SOCK_STREAM,0);
  358.         seteol(Curproc->output,Eol);
  359.         sockmode(Curproc->output,SOCK_ASCII);
  360.     } else
  361.         sp->input = sp->output = -1;
  362. #ifdef TRACE
  363.     if(type == COMMAND && Trace) {
  364.         Trace->input = sp->input;
  365.         Trace->output = sp->output;
  366.     }
  367. #endif
  368.   
  369.     /* on by default */
  370.     sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
  371.     sp->flowmode = 0;   /* Off by default */
  372.     sp->row = Numrows - 1 - StatusLines;
  373.     sp->morewait = 0;
  374.     sp->split = split;
  375.     newscreen(sp);
  376.     swapscreen(Current,sp);
  377.     Current = sp;
  378. #ifdef STATUSWIN
  379.     UpdateStatus();
  380. #endif
  381.     return sp;
  382. }
  383. void
  384. freesession(sp)
  385. struct session *sp;
  386. {
  387.     if(sp == NULLSESSION)
  388.         return;
  389.     pwait(NULL);    /* Wait for any pending output to go */
  390.     rflush();
  391.   
  392.     if(sp->proc1 != NULLPROC)
  393.         killproc(sp->proc1);
  394.     sp->proc1 = NULLPROC;
  395.     if(sp->proc2 != NULLPROC)
  396.         killproc(sp->proc2);
  397.     sp->proc2 = NULLPROC;
  398.   
  399.     free_p(sp->ttystate.line);
  400.     sp->ttystate.line = NULLBUF;
  401.     if(sp->s != -1)
  402.         close_s(sp->s);
  403.     if(sp->record != NULLFILE){
  404.         fclose(sp->record);
  405.         sp->record = NULLFILE;
  406.     }
  407.     free(sp->rfile);
  408.     sp->rfile = NULLCHAR;
  409.     if(sp->upload != NULLFILE){
  410.         fclose(sp->upload);
  411.         sp->upload = NULLFILE;
  412.     }
  413.     free(sp->ufile);
  414.     sp->ufile = NULLCHAR;
  415.     free(sp->name);
  416.     sp->name = NULLCHAR;
  417.     sp->type = FREE;
  418.   
  419.     close_s(sp->input);
  420.     sp->input = -1;
  421.     sp->proc->input = -1;
  422.     close_s(sp->output);
  423.     sp->output = -1;
  424.     sp->proc->output = -1;
  425.   
  426.     freescreen(sp);
  427.     if(Current == sp){
  428.         Current = Command;
  429.         swapscreen(NULLSESSION,Command);
  430. #ifdef STATUSWIN
  431.         UpdateStatus();
  432. #endif
  433. #ifndef LINUX
  434.         alert(Display,1);
  435. #endif
  436.     }
  437.     if(Lastcurr == sp)
  438.         Lastcurr = NULLSESSION;
  439. }
  440. #ifdef ALLCMD
  441. /* Control session recording */
  442. int
  443. dorecord(argc,argv,p)
  444. int argc;
  445. char *argv[];
  446. void *p;
  447. {
  448.     struct session *sp;
  449.     char *mode;
  450.   
  451.     sp = (struct session *)p;
  452.     if(sp == NULLSESSION){
  453.         tputs("No current session\n");
  454.         return 1;
  455.     }
  456.     if(argc > 1){
  457.         if(sp->rfile != NULLCHAR){
  458.             fclose(sp->record);
  459.             free(sp->rfile);
  460.             sp->record = NULLFILE;
  461.             sp->rfile = NULLCHAR;
  462.         }
  463.         /* Open new record file, unless file name is "off", which means
  464.          * disable recording
  465.          */
  466.         if(strcmp(argv[1],"off") != 0){
  467.             if(sockmode(sp->output,-1) == SOCK_ASCII)
  468.                 mode = APPEND_TEXT;
  469.             else
  470.                 mode = APPEND_BINARY;
  471.   
  472.             if((sp->record = fopen(argv[1],mode)) == NULLFILE)
  473.                 tprintf("Can't open %s: %s\n",argv[1],sys_errlist[errno]);
  474.             else
  475.                 sp->rfile = strdup(argv[1]);
  476.         }
  477.     }
  478.     if(sp->rfile != NULLCHAR)
  479.         tprintf("Recording into %s\n",sp->rfile);
  480.     else
  481.         tputs("Recording off\n");
  482.     return 0;
  483. }
  484. /* Control file transmission */
  485. int
  486. doupload(argc,argv,p)
  487. int argc;
  488. char *argv[];
  489. void *p;
  490. {
  491.     register struct session *sp;
  492.   
  493.     sp = (struct session *)p;
  494.     if(sp == NULLSESSION){
  495.         tputs("No current session\n");
  496.         return 1;
  497.     }
  498.     if(argc < 2){
  499.         if(sp->ufile != NULLCHAR)
  500.             tprintf("Uploading %s\n",sp->ufile);
  501.         else
  502.             tputs("Uploading off\n");
  503.         return 0;
  504.     }
  505.     if(strcmp(argv[1],"stop") == 0 && sp->upload != NULLFILE){
  506.         /* Abort upload */
  507.         fclose(sp->upload);
  508.         sp->upload = NULLFILE;
  509.         free(sp->ufile);
  510.         sp->ufile = NULLCHAR;
  511.         killproc(sp->proc2);
  512.         sp->proc2 = NULLPROC;
  513.         return 0;
  514.     }
  515.     /* Open upload file */
  516.     if((sp->upload = fopen(argv[1],READ_TEXT)) == NULLFILE){
  517.         tprintf("Can't read %s: %s\n",argv[1],sys_errlist[errno]);
  518.         return 1;
  519.     }
  520.     sp->ufile = strdup(argv[1]);
  521.     /* All set, invoke the upload process */
  522.     sp->proc2 = newproc("upload",1024,upload,0,sp,NULL,0);
  523.     return 0;
  524. }
  525. /* File uploading task */
  526. void
  527. upload(unused,sp1,p)
  528. int unused;
  529. void *sp1;
  530. void *p;
  531. {
  532.     struct session *sp;
  533.     int oldf;
  534.     char *buf;
  535.   
  536.     sp = (struct session *)sp1;
  537.   
  538.     /* Disable newline buffering for the duration */
  539.     oldf = setflush(sp->s,-1);
  540.   
  541.     buf = mallocw(BUFSIZ);
  542.     while(fgets(buf,BUFSIZ,sp->upload) != NULLCHAR)
  543.         if(usputs(sp->s,buf) == EOF)
  544.             break;
  545.   
  546.     free(buf);
  547.     usflush(sp->s);
  548.     setflush(sp->s,oldf);
  549.     fclose(sp->upload);
  550.     sp->upload = NULLFILE;
  551.     free(sp->ufile);
  552.     sp->ufile = NULLCHAR;
  553.     sp->proc2 = NULLPROC;
  554. }
  555. #endif /*ALLCMD*/
  556.